/*
 * Copyright (c) 2006-2021, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2024-10-01     SliverWangs
 */

#include "drv_common.h"
#include "drv_if8080.h"

#define DRV_DEBUG
#define LOG_TAG                         "drv.if8080"
#include <drv_log.h>


static void drv_if8080_gpio_init(void)
{
    gpio_init_type  gpio_init_struct = {0};

    /* enable the gpio clock */
    crm_periph_clock_enable(CRM_GPIOC_PERIPH_CLOCK, TRUE);
    crm_periph_clock_enable(CRM_GPIOD_PERIPH_CLOCK, TRUE);
    crm_periph_clock_enable(CRM_GPIOE_PERIPH_CLOCK, TRUE);

    /* enable the xmc clock */
    crm_periph_clock_enable(CRM_XMC_PERIPH_CLOCK, TRUE);

    /*-- gpio configuration ------------------------------------------------------*/
    gpio_pin_mux_config(GPIOC, GPIO_PINS_SOURCE2, GPIO_MUX_14);
    gpio_pin_mux_config(GPIOC, GPIO_PINS_SOURCE4, GPIO_MUX_14);
    gpio_pin_mux_config(GPIOC, GPIO_PINS_SOURCE5, GPIO_MUX_14);
    gpio_pin_mux_config(GPIOC, GPIO_PINS_SOURCE11, GPIO_MUX_14);
    gpio_pin_mux_config(GPIOC, GPIO_PINS_SOURCE12, GPIO_MUX_14);
    gpio_pin_mux_config(GPIOD, GPIO_PINS_SOURCE5, GPIO_MUX_10);
    gpio_pin_mux_config(GPIOD, GPIO_PINS_SOURCE8, GPIO_MUX_12);
    gpio_pin_mux_config(GPIOD, GPIO_PINS_SOURCE9, GPIO_MUX_12);
    gpio_pin_mux_config(GPIOD, GPIO_PINS_SOURCE10, GPIO_MUX_12);
    gpio_pin_mux_config(GPIOD, GPIO_PINS_SOURCE14, GPIO_MUX_12);
    gpio_pin_mux_config(GPIOD, GPIO_PINS_SOURCE15, GPIO_MUX_12);

    gpio_pin_mux_config(GPIOE, GPIO_PINS_SOURCE7, GPIO_MUX_12);
    gpio_pin_mux_config(GPIOE, GPIO_PINS_SOURCE8, GPIO_MUX_12);
    gpio_pin_mux_config(GPIOE, GPIO_PINS_SOURCE9, GPIO_MUX_12);
    gpio_pin_mux_config(GPIOE, GPIO_PINS_SOURCE10, GPIO_MUX_12);
    gpio_pin_mux_config(GPIOE, GPIO_PINS_SOURCE11, GPIO_MUX_12);
    gpio_pin_mux_config(GPIOE, GPIO_PINS_SOURCE12, GPIO_MUX_12);
    gpio_pin_mux_config(GPIOE, GPIO_PINS_SOURCE13, GPIO_MUX_12);
    gpio_pin_mux_config(GPIOE, GPIO_PINS_SOURCE14, GPIO_MUX_12);
    gpio_pin_mux_config(GPIOE, GPIO_PINS_SOURCE15, GPIO_MUX_12);

    /* lcd data lines configuration */
    gpio_init_struct.gpio_pins = GPIO_PINS_2 | GPIO_PINS_4 | GPIO_PINS_5  | GPIO_PINS_11| GPIO_PINS_12;
    gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
    gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
    gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
    gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
    gpio_init(GPIOC, &gpio_init_struct);

    gpio_init_struct.gpio_pins =  GPIO_PINS_5 | GPIO_PINS_8 | GPIO_PINS_9  | GPIO_PINS_10 | GPIO_PINS_14 | GPIO_PINS_15;
    gpio_init(GPIOD, &gpio_init_struct);

    gpio_init_struct.gpio_pins =  GPIO_PINS_7 | GPIO_PINS_8 | GPIO_PINS_9 | GPIO_PINS_10 | GPIO_PINS_11 | GPIO_PINS_12 | GPIO_PINS_13 | GPIO_PINS_14 | GPIO_PINS_15;
    gpio_init(GPIOE, &gpio_init_struct);
}


/**
  * @brief  configures the xmc and gpios to interface with the lcd.
  *         this function must be called before any write/read operation
  *         on the lcd.
  * @param  none
  * @retval none
  */
void drv_if8080_init(void)
{
    xmc_norsram_init_type  xmc_norsram_init_struct;
    xmc_norsram_timing_init_type rw_timing_struct, w_timing_struct;

    drv_if8080_gpio_init();

    /*-- xmc configuration ------------------------------------------------------*/
    xmc_norsram_default_para_init(&xmc_norsram_init_struct);
    xmc_norsram_init_struct.subbank = XMC_BANK1_NOR_SRAM4;
    xmc_norsram_init_struct.data_addr_multiplex = XMC_DATA_ADDR_MUX_DISABLE;
    xmc_norsram_init_struct.device = XMC_DEVICE_SRAM;
    xmc_norsram_init_struct.bus_type = XMC_BUSTYPE_16_BITS;
    xmc_norsram_init_struct.burst_mode_enable = XMC_BURST_MODE_DISABLE;
    xmc_norsram_init_struct.asynwait_enable = XMC_ASYN_WAIT_DISABLE;
    xmc_norsram_init_struct.wait_signal_lv = XMC_WAIT_SIGNAL_LEVEL_LOW;
    xmc_norsram_init_struct.wrapped_mode_enable = XMC_WRAPPED_MODE_DISABLE;
    xmc_norsram_init_struct.wait_signal_config = XMC_WAIT_SIGNAL_SYN_BEFORE;
    xmc_norsram_init_struct.write_enable = XMC_WRITE_OPERATION_ENABLE;
    xmc_norsram_init_struct.wait_signal_enable = XMC_WAIT_SIGNAL_DISABLE;
    xmc_norsram_init_struct.write_timing_enable = XMC_WRITE_TIMING_ENABLE;
    xmc_norsram_init_struct.write_burst_syn = XMC_WRITE_BURST_SYN_DISABLE;
    xmc_nor_sram_init(&xmc_norsram_init_struct);

    /* timing configuration */
    xmc_norsram_timing_default_para_init(&rw_timing_struct, &w_timing_struct);
    rw_timing_struct.subbank = XMC_BANK1_NOR_SRAM4;
    rw_timing_struct.write_timing_enable = XMC_WRITE_TIMING_ENABLE;
    rw_timing_struct.addr_setup_time = 0xf;
    rw_timing_struct.addr_hold_time = 0x0;
    rw_timing_struct.data_setup_time = 0xf;
    rw_timing_struct.bus_latency_time = 0x0;
    rw_timing_struct.clk_psc = 0x0;
    rw_timing_struct.data_latency_time = 0x0;
    rw_timing_struct.mode = XMC_ACCESS_MODE_A;
    w_timing_struct.subbank = XMC_BANK1_NOR_SRAM4;
    w_timing_struct.write_timing_enable = XMC_WRITE_TIMING_ENABLE;
    w_timing_struct.addr_setup_time = 0x2;
    w_timing_struct.addr_hold_time = 0x0;
    w_timing_struct.data_setup_time = 0x2;
    w_timing_struct.bus_latency_time = 0x0;
    w_timing_struct.clk_psc = 0x0;
    w_timing_struct.data_latency_time = 0x0;
    w_timing_struct.mode = XMC_ACCESS_MODE_A;
    xmc_nor_sram_timing_config(&rw_timing_struct, &w_timing_struct);

    /* bus turnaround phase for consecutive read duration and consecutive write duration */
    xmc_ext_timing_config(XMC_BANK1_NOR_SRAM4, 0x08, 0x08);

    /* enable xmc_bank1_nor_sram4 */
    xmc_nor_sram_enable(XMC_BANK1_NOR_SRAM4, TRUE);
}


/**
  * @brief  this function is write command to lcd.
  * @param  command : the command to write.
  * @retval none
  */
void drv_if8080_write_command(uint16_t command)
{
  *(__IO uint16_t*) XMC_LCD_COMMAND = command;
}

/**
  * @brief  this function is write data to lcd.
  * @param  data : the data to write.
  * @retval none
  */
void drv_if8080_write_data(uint16_t data)
{
  *(__IO uint16_t*) XMC_LCD_DATA = data;
}

/**
  * @brief  this function is Read data from lcd.
  * @param  data : the data to write.
  * @retval none
  */
uint16_t drv_if8080_read_data(void)
{
  return *(uint16_t*)XMC_LCD_DATA;
}


